package com.elasticsearch.service;

import com.alibaba.fastjson.JSONObject;
import com.elasticsearch.util.Func;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ElasticsearchService {
    /**
     * 注入es操作对象
     */
    @Resource
    TransportClient transportClient;

    private static final DateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.CHINA);
    private static final DateFormat FORMAT1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    public Object get(JSONObject jsonObject) {
        Map innerMap = jsonObject.getInnerMap();
        return getBoolDataByMuchField("type", innerMap);
    }

    public Object getFuzzyQuery(JSONObject jsonObject) {
        Map innerMap = jsonObject.getInnerMap();
        return getDataByMuchillegible("type", innerMap);
    }

    public String save(JSONObject jsonObject) throws IOException {
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject();
        Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            xContentBuilder.field(next.getKey(), Func.toStr(next.getValue(),""));
        }
        xContentBuilder.endObject();
        IndexResponse indexResponse =
                transportClient.prepareIndex("index", "type", jsonObject.getString("id")).setSource(xContentBuilder).get();
        return indexResponse.getId();
    }



    public Object update(JSONObject jsonObject, String id) throws IOException {
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                .startObject();
        Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            xContentBuilder.field(next.getKey(), next.getValue());
        }
        xContentBuilder.endObject();
        UpdateResponse response = transportClient.prepareUpdate("index", "type", id)
                .setDoc(xContentBuilder).get();
        return response.getId();
    }

//    public Object delete(String ids) {
//        String[] idArr = Func.split(ids, ",");
//        StringBuilder sb = new StringBuilder();
//        for (String id : idArr) {
//            DeleteResponse deleteResponse = transportClient.prepareDelete("index", "type", id).execute().actionGet();
//            sb.append(deleteResponse.getId());
//            sb.append("_");
//        }
//        sb.delete(sb.length() - 1, sb.length());
//        return sb.toString();
//    }

    /**
     * 多条件  文档名、字段名、字段值，查询某一条记录的详细信息
     *
     * @param type 文档名，相当于oracle中的表名，例如：ql_xz
     * @param map  字段名：字段值 的map
     * @return List
     * @author
     */
    public List getBoolDataByMuchField(String type, Map<String, String> map) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        for (String in : map.keySet()) {
            //map.keySet()返回的是所有key的值
            //得到每个key多对用value的值
            String str = map.get(in);
            boolQueryBuilder.must(QueryBuilders.matchPhraseQuery(in, str));
        }
        SearchResponse response = transportClient.prepareSearch("index").setTypes(type)
                .addDocValueField("_id")
                .setQuery(boolQueryBuilder)
                .setFrom(0).setSize(10000).setExplain(true)
                .execute()
                .actionGet();
        return responseToList(transportClient, response);
    }

    /**
     * 多条件 模糊查询
     *
     * @param type type 文档名，相当于oracle中的表名，例如：ql_xz
     * @param map  包含key:value 模糊值键值对
     * @return List
     * @author
     */
    public List getDataByMuchillegible(String type, Map<String, String> map) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchAllQuery());
        for (String in : map.keySet()) {
            //map.keySet()返回的是所有key的值
            //得到每个key多对用value的值
            String str = map.get(in);
            boolQueryBuilder.must(QueryBuilders.matchPhraseQuery(in, "*" + str + "*"));
        }
        SearchResponse response = transportClient.prepareSearch("index").setTypes(type)
                .setQuery(boolQueryBuilder)
                .setFrom(0).setSize(10000).setExplain(true)
                .execute().actionGet();

        return responseToList(transportClient, response);
    }

    /**
     * 将查询后获得的response转成list
     *
     * @param client
     * @param response
     * @return
     */
    public List responseToList(TransportClient client, SearchResponse response) {
        SearchHits hits = response.getHits();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < hits.getHits().length; i++) {
            Map<String, Object> map = hits.getAt(i).getSourceAsMap();
            list.add(map);
        }
        return list;
    }
}
